/*
 * ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
 */

package org.modelcc.parser;

import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.modelcc.IModel;

/**
 * ModelCC Parser
 * @param <T> the parser type
 * 
 * @author Luis Quesada (lquesada@modelcc.org) & Fernando Berzal (fberzal@modelcc.org)
 */
public abstract class Parser<T> implements Serializable {

    /**
     * Parses an input string
     * @param input the input string
     * @return a parsed object
     */
    public T parse(String input) throws ParserException {
        return parse(new StringReader(input));        
    };

    /**
     * Parses an input reader
     * @param input the input reader
     * @return a parsed object
     */
    public abstract T parse(Reader input) throws ParserException;

    /**
     * Parses an input string
     * @param input the input string
     * @return a collection of parsed objects
     */
    public Collection<T> parseAll(String input) throws ParserException {
        return parseAll(new StringReader(input));
    }

    /**
     * Parses an input reader
     * @param input the input reader
     * @return a collection of parsed objects
     */
    public abstract Collection<T> parseAll(Reader input) throws ParserException;

    /**
     * Parses an input string
     * @param input the input string
     * @return an iterator to the collection of parsed objects
     */
    public Iterator<T> parseIterator(String input) throws ParserException {
        return parseIterator(new StringReader(input));
    }

    /**
     * Parses an input reader
     * @param input the input reader
     * @return an iterator to the collection of parsed objects
     */
    public abstract Iterator<T> parseIterator(Reader input) throws ParserException;

    /**
     * Returns the parsing metadata for an object.
     * @param object an object instantiated during the parsing.
     * @return the parsing metadata.
     */
    public abstract Map<String,Object> getParsingMetadata(Object object);

    
	// Predefined references
	// ---------------------
	
	protected List<IModel> predefined = new ArrayList<IModel>();
	
	/**
	 * Add predefined model element
	 */
	public final void add (IModel model) 
	{
		predefined.add(model);
	}
	
	/**
	 * Remove predefined model element
	 */
	public final void remove (IModel model) 
	{
		predefined.add(model);
	}
	
	/**
	 * Remove predefined model element
	 */
	public final void clear () 
	{
		predefined.clear();
	}
    
}
